package nccloud.mob.riart.message.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import itf.approvecenter.util.DataExchangeBean;
import itf.approvecenter.util.InteractiveExceptionContext;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.NCLocator;
import nc.jdbc.framework.processor.BeanProcessor;
import nc.vo.pf.change.PfUtilBaseTools;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.pf.AssignableInfo;
import nc.vo.pub.pf.TransitionSelectableInfo;
import nc.vo.pub.pf.workflow.IPFActionName;
import nc.vo.pub.workflownote.WorkflownoteVO;
import nc.vo.wfengine.definition.WorkflowTypeEnum;
import nccloud.base.exception.ExceptionUtils;
import nccloud.bs.message.itf.IMessageSyncService;
import nccloud.commons.lang.StringUtils;
import nccloud.framework.mob.action.itf.IMobileAction;
import nccloud.framework.mob.container.IMobRequest;
import nccloud.framework.mob.container.MobClientInfo;
import nccloud.framework.service.ServiceLocator;
import nccloud.itf.uap.pf.IApproveBusiHandler;
import nccloud.itf.uap.pf.NCCWorkFlowService;
import nccloud.message.vo.NCCMessageVO;
import nccloud.putitf.riart.billtype.IBilltypeService;
import nccloud.utils.mobile_riart.MessageLogger;
import nccloud.utils.riart.MessageEventTypeEnum;
import nccloud.web.workflow.approvalcenter.action.ApproveOrSignalActionUtil;
import nccloud.web.workflow.approvalcenter.action.AssginUtil;
import nccloud.web.workflow.approvalcenter.action.NCCFlowInteractiveConstant;
import nccloud.web.workflow.approvalcenter.action.PfChecknoteEnum;
import nccloud.web.workflow.approve.util.ApproveWorkitemAssistor;
import nccloud.web.workflow.approve.util.NCCFlowUtils;
import nccloud.web.workflow.approve.util.NCCMsgContext;

public class ApprovePassAction implements IMobileAction {
	Set<String> busiexceptionCodeSet = new HashSet<String>();

	@Override
	public Object doAction(IMobRequest request) {
		MessageLogger.info("第三方调用移动端审批通过【nccloud.mob.riart.message.actions.ApprovePassAction】，开始调用NCC移动端审批接口...........");
		String jsonStr = request.read();
		JSONObject json2 = JSONObject.parseObject(jsonStr);

		HashMap<Object, Object> hmPfExParams = new HashMap<Object, Object>();
		// 构造参数信息到map中
		DataExchangeBean bean = new DataExchangeBean();
		bean.setCode(NCCFlowInteractiveConstant.SUCCESS);
		NCCMsgContext nccMsg = new NCCMsgContext(request.read());
		Map<String, Object> paramInfoMap = nccMsg.getMsgINfoContext();

		// 验证非空的参数
		String[] flowParameterArray = { NCCFlowInteractiveConstant.BILL_TYPE,
				NCCFlowInteractiveConstant.BILL_ID,
				NCCFlowInteractiveConstant.CHECK_FLOW, };

		if (NCCFlowUtils.isFlowParameterArrayNull(flowParameterArray,
				paramInfoMap)) {
			return NCCFlowUtils
					.exchangeDataMsg(
							bean,
							NCCFlowInteractiveConstant.ERROR,
							nc.vo.ml.NCLangRes4VoTransl.getNCLangRes()
							.getStrByID("0020nccloud_0",
									"0ncc0020001-0428")/* @res 流程参数为空 */);
		}
		// 构造所需参数
		String billTypeOrTransType = paramInfoMap.get(
				NCCFlowInteractiveConstant.BILL_TYPE).toString();
		String billId = paramInfoMap.get(NCCFlowInteractiveConstant.BILL_ID)
				.toString();
		String pk_checkflow = paramInfoMap.get(
				NCCFlowInteractiveConstant.CHECK_FLOW).toString();
		// start modify wy by 20230620
		updateApprovePassMessage(pk_checkflow);
		// end modify by wy
		String check_note = json2.getString("check_note");

		String skipcodes = json2
				.getString(NCCFlowInteractiveConstant.SKIP_CODES);
		MobClientInfo info = new MobClientInfo();
		// SessionContext.getInstance().getClientInfo().setUserid(info.getUserid());
		// 校验消息是否有效
		NCCFlowUtils.checkIsExistMessage(billTypeOrTransType, billId);

		// 前台的业务编码、并将该编码信息保放到环境变量中、现在放的为String
		String paramBusiCodes = null;
		if (paramInfoMap.get(NCCFlowInteractiveConstant.SKIP_CODES) != null
				&& !"[]".equals(paramInfoMap.get(
						NCCFlowInteractiveConstant.SKIP_CODES).toString())) {

			paramBusiCodes = paramInfoMap
					.get(NCCFlowInteractiveConstant.SKIP_CODES)
					.toString()
					.substring(
							1,
							paramInfoMap
							.get(NCCFlowInteractiveConstant.SKIP_CODES)
							.toString().length() - 1).replace("\"", "");
		}

		// 运行参数 放到map中方便判断是否为空（直接放入参数名称即可）
		List<Map<String, Object>> paraMapList = new ArrayList<Map<String, Object>>();
		Map paraMap = new HashMap();
		paraMap.put(NCCFlowInteractiveConstant.NCCFlOW_PARAMTER,
				NCCFlowInteractiveConstant.NCCLOUD);

		if (paramBusiCodes != null) {
			paraMap.put(NCCFlowInteractiveConstant.NCC_BUSICODES,
					paramBusiCodes);
		}
		paraMapList.add(paraMap);

		NCCWorkFlowService nccWorkFlowService = ServiceLocator
				.find(NCCWorkFlowService.class);
		AggregatedValueObject billvo = null;

		WorkflownoteVO note = null;

		try {

			billvo = nccWorkFlowService.mobileAppUtilForQueryBillEntity(
					billTypeOrTransType, billId);
		} catch (BusinessException e) {
			MessageLogger.error("第三方调用移动端审批通过接口失败，失败原因【"+e.getMessage()+"】...........");
			ExceptionUtils.wrapBusinessException(nc.vo.ml.NCLangRes4VoTransl
					.getNCLangRes().getStrByID("0020nccloud_0",
							"0ncc0020001-0430")/* @res 该单据异常，请刷新页面重试！ */);
		}catch(Exception e) {
			MessageLogger.error("第三方调用移动端审批通过接口失败，失败原因【"+e.getMessage()+"】...........");
		}

		try {
			note = nccWorkFlowService.checkWorkflowActions(billTypeOrTransType,
					billId,

					pk_checkflow);

			if (note == null) {
				hmPfExParams.put(PfUtilBaseTools.PARAM_NOTE_CHECKED,
						PfUtilBaseTools.PARAM_NOTE_CHECKED);
			} else {
				hmPfExParams.put(PfUtilBaseTools.PARAM_WORKNOTE, note);
			}

			NCCFlowUtils.checkIsCopySend(note,
					JSONObject.parseObject(request.read()));
		} catch (BusinessException e2) {
			ExceptionUtils.wrapException(e2);
		}catch(Exception e) {
			MessageLogger.error("第三方调用移动端审批通过接口失败，失败原因【"+e.getMessage()+"】...........");
		}

		// 2.如果是的将数据信息返回在前台显示，获得数据再次提交
		if (paramInfoMap.get("isAssgin") == null
				|| (paramInfoMap.get("isAssgin") != null && !(Boolean) paramInfoMap
				.get("isAssgin"))) {

			JSONObject assginre = new AssginUtil().getAssginResult(note);

			if (assginre != null) {
				return assginre;
			}
		}

		// 此处判断指派逻辑：
		// 1.第一次过来的时候isAssgin根据消息里面的是否批量传过来
		// 2.如果是的将数据信息返回在前台显示，获得数据再次提交
		if (paramInfoMap.get("isAssgin") != null
				&& (Boolean) paramInfoMap.get("isAssgin")) {

			if (note.getWorkflow_type() == 2 || note.getWorkflow_type() == 3
					|| note.getWorkflow_type() == 6) {

				if (paramInfoMap.get("assgininfo") != null) {
					JSONObject jsondata = (JSONObject) paramInfoMap
							.get("assgininfo");
					// 得到可指派的输入数据
					Vector assignInfos = note.getTaskInfo()
							.getAssignableInfos();

					List<Object> jsonArayList = (List<Object>) jsondata
							.get("content");

					JSONArray jsonAray = new JSONArray(jsonArayList);

					for (Object obj : jsonAray) {
						JSONObject json = new JSONObject((Map) obj);

						if (assignInfos != null && assignInfos.size() > 0) {

							for (int i = 0; i < assignInfos.size(); i++) {

								AssignableInfo assignInfo = (AssignableInfo) assignInfos
										.get(i);
								String activitydefid = json
										.getString("activitydefid");
								if (activitydefid.equals(assignInfo
										.getActivityDefId())) {
									Vector<String> userPKs = assignInfo
											.getAssignedOperatorPKs();
									userPKs.clear();
									JSONArray listStr = new JSONArray(
											(List<Object>) json.get("uservos"));
									for (Object jsonobj : listStr) {
										JSONObject json11 = new JSONObject(
												(Map) jsonobj);
										// JSONObject json11 = (JSONObject)obj;
										userPKs.addElement(json11
												.getString("userpk"));
									}
									break;
								}

							}

						}

					}

				}

			} else {
				if (paramInfoMap.get("assgininfo") != null) {
					JSONObject jsondata = (JSONObject) paramInfoMap
							.get("assgininfo");
					if (jsondata.get("muplityWithOutAssgin") != null) {
						if (jsondata.getBooleanValue("muplityWithOutAssgin")) {
							// 得到可指派的输入数据
							Vector assignInfos = note.getTaskInfo()
									.getAssignableInfos();

							List<Object> jsonArayList = (List<Object>) jsondata
									.get("content");

							JSONArray jsonAray = new JSONArray(jsonArayList);

							for (Object obj : jsonAray) {
								JSONObject json = new JSONObject((Map) obj);
								// JSONObject json = (JSONObject)obj;

								if (assignInfos != null
										&& assignInfos.size() > 0) {

									for (int i = 0; i < assignInfos.size(); i++) {

										AssignableInfo assignInfo = (AssignableInfo) assignInfos
												.get(i);
										String activitydefid = json
												.getString("selectpath");
										if (assignInfo.getActivityDefId()
												.equals(activitydefid)) {
											Vector<String> userPKs = assignInfo
													.getAssignedOperatorPKs();
											userPKs.clear();
											JSONArray listStr = new JSONArray(
													(List<Object>) json
													.get("assginUsers"));
											for (Object jsonobj : listStr) {
												JSONObject json11 = new JSONObject(
														(Map) jsonobj);
												// JSONObject json11 =
												// (JSONObject)obj;
												userPKs.addElement(json11
														.getString("pk"));
											}
											break;
										}

									}

								}

							}
						} else {
							// 实际：传过来获取只有一个，然后去匹配有没有指派
							Vector assignInfos = note.getTaskInfo()
									.getAssignableInfos();
							Vector tSelectInfos = note.getTaskInfo()
									.getTransitionSelectableInfos();

							// 循环获取传过来的值

							JSONObject jsondata11 = (JSONObject) paramInfoMap
									.get("assgininfo");
							List<Object> jsonArayList = (List<Object>) jsondata11
									.get("content");

							JSONArray jsonAray = new JSONArray(jsonArayList);

							for (Iterator iterator = jsonAray.iterator(); iterator
									.hasNext();) {
								JSONObject jsonObject = (JSONObject) iterator
										.next();

								if (jsonObject.getBoolean("isChoice")) {
									for (int j = 0; j < assignInfos.size(); j++) {
										AssignableInfo _assignInfos = (AssignableInfo) assignInfos
												.get(j);

										// assgin.getAfferentTransitions().containsKey(trans.getTransitionDefId())
										if (_assignInfos
												.getAfferentTransitions()
												.containsKey(
														jsonObject
														.getString("selectpath"))) {
											List<Object> userJsonList = (List<Object>) jsonObject
													.get("assginUsers");
											if (userJsonList != null
													&& userJsonList.size() > 0) {
												JSONArray userListJson = new JSONArray(
														userJsonList);
												_assignInfos
												.getAssignedOperatorPKs()
												.clear();
												for (Object obj : userListJson) {
													JSONObject jsonu = (JSONObject) obj;
													_assignInfos
													.getAssignedOperatorPKs()
													.add(jsonu
															.getString("pk"));

												}

											}
										}

									}
								}
							}

							for (Iterator iterator = jsonAray.iterator(); iterator
									.hasNext();) {

								JSONObject jsonObject = (JSONObject) iterator
										.next();
								if (jsonObject.getBoolean("isChoice")) {
									for (int i = 0; i < tSelectInfos.size(); i++) {
										TransitionSelectableInfo trans = (TransitionSelectableInfo) tSelectInfos
												.get(i);
										if (jsonObject.getString("selectpath")
												.equals(trans
														.getTransitionDefId())) {
											trans.setChoiced(true);
										} else {
											trans.setChoiced(false);
										}

									}

								}

							}

						}

					}

				}

			}
		}

		// 审批前的检查类
		String billtype2RegistClass = "";
		IApproveBusiHandler approveBusiAction = null;
		try {
			IBilltypeService billTypeServiceImpl = ServiceLocator
					.find(IBilltypeService.class);
			// 获取原始单据类型编码

			// BilltypeVO btVO111
			// =PfDataCache.getBillTypeInfo(SessionContext.getInstance().getClientInfo().getPk_group(),billTypeOrTransType);

			String billType = nccWorkFlowService
					.getRealBilltype(billTypeOrTransType);

			// PfDataCache.getBillTypeInfo(SessionContext.getInstance().getClientInfo().getPk_group(),billTypeOrTransType).getPk_billtypecode();
			// String billType =
			// billTypeServiceImpl.getRealBilltype(billTypeOrTransType).getPk_billtypecode();

			// 获取单据上的审批前检查类
			if (billTypeServiceImpl.queryBilltypeVOsFromCache(billType, 25) != null
					&& billTypeServiceImpl.queryBilltypeVOsFromCache(billType,
							25).size() > 0) {

				billtype2RegistClass = billTypeServiceImpl
						.queryBilltypeVOsFromCache(billType, 25).get(0)
						.getClassname();
			}

			if (!"".equals(billtype2RegistClass)
					&& billtype2RegistClass != null) {

				Class clazz = Class.forName(billtype2RegistClass);

				if ((nccloud.pubitf.platform.approve.AbstractApproveBusiHandlerImpl.class)
						.isAssignableFrom(clazz)) {

					nccloud.pubitf.platform.approve.AbstractApproveBusiHandlerImpl approveBusiClass = (nccloud.pubitf.platform.approve.AbstractApproveBusiHandlerImpl) clazz
							.newInstance();

					InteractiveExceptionContext context = new InteractiveExceptionContext();
					context.setBilltype(billTypeOrTransType);
					context.setArgsList(note.getApplicationArgs());
					context.setBillId(billId);
					if (StringUtils.isNotEmpty(skipcodes)
							&& (!"[]".equals(skipcodes))) {
						context.setSkipcodes(String.valueOf(skipcodes)
								.substring(1, skipcodes.length() - 1)
								.split(","));
					} else {
						context.setSkipcodes(null);
					}
					context.setBillVos(new AggregatedValueObject[] { billvo });
					// for 资产的特殊处理
					if (approveBusiClass.checkBeforeIsRunMethodParam(context) != null
							&& NCCFlowInteractiveConstant.RunMethodParam
							.equals(approveBusiClass
									.checkBeforeIsRunMethodParam(
											context).getCode())) {

						bean = approveBusiClass
								.checkBeforeApproveWithArgList(context);
						if (bean != null
								&& StringUtils.isNotEmpty(bean.getCode())
								&& !("200".equals(bean.getCode()))) {
							return JSONObject.toJSON(bean);
						}
					}

					bean = approveBusiClass.checkBeforeApprove(
							billTypeOrTransType, billId, billvo);
					if (bean != null && StringUtils.isNotEmpty(bean.getCode())
							&& !("200".equals(bean.getCode()))) {
						return JSONObject.toJSON(bean);
					}

				} else {
					approveBusiAction = (IApproveBusiHandler) clazz
							.newInstance();

					bean = approveBusiAction.checkBeforeApprove(
							billTypeOrTransType, billId, billvo);
					if (bean != null && StringUtils.isNotEmpty(bean.getCode())
							&& !("200".equals(bean.getCode()))) {
						return JSONObject.toJSON(bean);
					}
				}

			}
		} catch (Exception e1) {
			ExceptionUtils.wrapException(e1);
			return NCCFlowUtils.exchangeDataMsg(
					bean,
					NCCFlowInteractiveConstant.ERROR,
					nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
							"0020nccloud_0", "0ncc0020001-0431")/*
							 * @res
							 * 请检查审批前检查注册类
							 */
					+ e1.getMessage());
		}

		// 封装 notevo 进入审批操作
		note.setApproveresult(UFBoolean.TRUE.toString());
		if (StringUtils.isEmpty(check_note)) {
			check_note = NCCFlowUtils
					.getIndividualCheckNote(PfChecknoteEnum.PASS);
			note.setChecknote(check_note);
		} else {
			note.setChecknote(check_note);
		}
		// 进行附件的处理：

		NCCFlowUtils.handleAttrfiles(json2, note);

		// 执行后台审批逻辑
		String result = ApproveWorkitemAssistor
				.sign(note,
						getCheckNotePulsApproveResult(check_note,
								PfChecknoteEnum.PASS));
		if (StringUtils.isEmpty(result)) {
			try {
				// 进行审批流的判断
				if (WorkflowTypeEnum.fromIntValue(note.getWorkflow_type())
						.equals(WorkflowTypeEnum.Approveflow)
						|| WorkflowTypeEnum.fromIntValue(
								note.getWorkflow_type()).equals(
										WorkflowTypeEnum.SubApproveflow)) {

					bean = ApproveOrSignalActionUtil.processAction(
							IPFActionName.APPROVE, billTypeOrTransType, note,
							billvo, paraMapList, null, billtype2RegistClass);
				} else {
					bean = ApproveOrSignalActionUtil.processAction(
							IPFActionName.SIGNAL, billTypeOrTransType, note,
							billvo, paraMapList, null, billtype2RegistClass);
				}

			} catch (BusinessException e) {
				MessageLogger.error("第三方调用移动端审批通过接口失败，失败原因【"+e.getMessage()+"】...........");
				ExceptionUtils.wrapException(e);

			}catch(Exception e) {
				MessageLogger.error("第三方调用移动端审批通过接口失败，失败原因【"+e.getMessage()+"】...........");
			}
		}
		//		return (JSONObject) JSONObject.toJSON(bean);
		return null;
	}

	/**
	 * 预先获得批语
	 * */
	public String getCheckNotePulsApproveResult(String checknote,
			PfChecknoteEnum check) {
		if (check == PfChecknoteEnum.PASS) {
			// 批准
			checknote += UFBoolean.valueOf(true).toString();
		} else if (check == PfChecknoteEnum.NOPASS) {
			// 不批准
			checknote += UFBoolean.valueOf(false).toString();
		} else if (check == PfChecknoteEnum.REJECT) {
			// 驳回到制单人
			checknote += "R";
		}
		return checknote;
	}
	

	// satrt eidt wy by 20230612
	/**
	 * 修改消息推送第三方
	 * @param pk_datail 消息详情主键
	 * @throws DAOException 
	 */
	public void updateApprovePassMessage(String pk_datail) {
		MessageLogger.info("进入 【nccloud.web.workflow.approvalcenter.action.ApprovePassAction】 类中方法【updateApprovePassMessage】 ");
		try {
			NCCMessageVO tempMsgVos = (NCCMessageVO)new BaseDAO().executeQuery("select * from sm_msg_approve where pk_detail = '"+pk_datail+"'", 
					new BeanProcessor(NCCMessageVO.class)); 
			ServiceLocator.find(IMessageSyncService.class).setMessageCache(new NCCMessageVO[] {tempMsgVos}, MessageEventTypeEnum.UPDATE);
		}catch(Exception e) {
			MessageLogger.error("已读消息推送第三方失败【nccloud.web.workflow.approvalcenter.action.ApprovePassAction】，失败原因: " + e.getMessage());
		}
		
	}
	// end by wy

}
